//
// Created by YueChuan on 2023/5/8.
//

#ifndef YUECHUAN_URI_H
#define YUECHUAN_URI_H

#include <memory>
#include <string>
#include <stdint.h>
#include "address.h"

namespace yuechuan {
    /*
     foo://user@sylar.com:8042/over/there?name=ferret#nose
       \_/   \______________/\_________/ \_________/ \__/
        |           |            |            |        |
     scheme     authority       path        query   fragment
    */
    class Uri {
    private:

        ///Scheme
        std::string m_scheme;
        /// 用户信息
        std::string m_userinfo;
        /// 主机
        std::string m_host;
        /// 端口号
        int32_t m_port;
        /// 路径
        std::string m_path;
        /// 查询字符串
        std::string m_query;
        /// 附加值
        std::string m_fragment;


    public:
        typedef std::shared_ptr<Uri> ptr;

        /**
         * @brief 创建uri对象
         * @param uri uri字符串对象
         * @return 解析成功返回的uri对象只能指针，解析失败返回nullptr
         */
        static ptr Create(const std::string &uri);

        /**
         * @brief 默认构造函数
         */
        Uri();

        /**
         * @brief 返回协议
         */
        const std::string &getScheme() const { return m_scheme; }

        /**
         * @brief 返回用户信息
         */
        const std::string &getUserinfo() const { return m_userinfo; }

        /**
         * @brief 返回主机
         */
        const std::string &getHost() const { return m_host; }

        /**
         * @brief 返回路径
         */
        const std::string &getPath() const;

        /**
         * @brief 获取查询字符串
         */
        const std::string &getQuery() const { return m_query; }

        /**
         * @brief 返回fragment
         */
        const std::string &getFragment() const { return m_fragment; }

        /**
         * @brief 返回端口
         */
        int32_t getPort() const;

        /**
         * 设置Scheme
         * @param scheme
         */
        void setScheme(const std::string &scheme) { m_scheme = scheme; }

        /**
         * @brief 设置用户信息
         */
        void setUserinfo(const std::string &userinfo) { m_userinfo = userinfo; }

        /**
         * @brief 设置主机
         */
        void setHost(const std::string &host) { m_host = host; }

        /**
         * @brief 设置路径
         */
        void setPath(const std::string &path) { m_path = path; }

        /**
        * @brief 设置端口号
        */
        void setPort(int32_t port) { m_port = port; }

        /**
         * @brief 设置查询字符串
         */
        void setQuery(const std::string &query) { m_query = query; }


        /**
         * @brief 设置附加字段
         */
        void setFragment(const std::string &fragment) { m_fragment = fragment; }

        /**
         * @brief 将uir转换为流式对象
         * @param os 输出控制流
         * @return std::ostream&
         */
        std::ostream &dump(std::ostream &os) const;

        /**
         * @brief 将Uri对象转换为字符串
         * @return std::string
         */
        std::string toString() const;

        /**
         * @brief 获取Address
         * @return Address::ptr
         */
        Address::ptr createAddress() const;

    private:
        /**
         * @brief 是否默认端口
         * @return
         */
        bool isDefaultPort() const;
    };
}// namespace yuechuan
#endif //YUECHUAN_URI_H
